package com.cloud.xtools.user.service.admin.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloud.xtools.common.exception.ServiceException;
import com.cloud.xtools.common.response.PageList;
import com.cloud.xtools.common.util.XPage;
import com.cloud.xtools.user.domain.entity.Permission;
import com.cloud.xtools.user.domain.entity.Role;
import com.cloud.xtools.user.domain.query.admin.RoleQuery;
import com.cloud.xtools.user.domain.request.admin.RoleCreateRequest;
import com.cloud.xtools.user.domain.request.admin.RoleUpdateRequest;
import com.cloud.xtools.user.domain.resource.admin.RoleResource;
import com.cloud.xtools.user.mapper.RoleMapper;
import com.cloud.xtools.user.service.admin.PermissionService;
import com.cloud.xtools.user.service.admin.RolePermissionService;
import com.cloud.xtools.user.service.admin.RoleService;
import com.cloud.xtools.user.service.admin.UserRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author Daixinguo
 */
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    private final RoleMapper roleMapper;

    private final RolePermissionService rolePermissionService;

    private final UserRoleService userRoleService;

    private final PermissionService permissionService;

    @Override
    public Long countByIds(List<Long> roleIds) {
        QueryWrapper<Role> queryWrapper = Wrappers.query();
        queryWrapper.in("id", roleIds);
        return count(queryWrapper);
    }

    @Override
    public PageList list(RoleQuery roleQuery) {
        QueryWrapper<Role> queryWrapper = Wrappers.query();
        if (!StrUtil.hasBlank(roleQuery.getName())) {
            queryWrapper.like("name", roleQuery.getName());
        }

        XPage.startPage(roleQuery.getPageNum(), roleQuery.getPageSize());

        List<Role> roles = roleMapper.roleList(queryWrapper);
        return XPage.page(roles, RoleResource.class);
    }

    @Override
    public RoleResource add(RoleCreateRequest roleCreateRequest) {
        Role role = BeanUtil.copyProperties(roleCreateRequest, Role.class);
        save(role);
        return BeanUtil.copyProperties(role, RoleResource.class);
    }

    @Override
    public void edit(Long id, RoleUpdateRequest roleUpdateRequest) {
        roleUpdateRequest.setId(id);
        Role role = BeanUtil.copyProperties(roleUpdateRequest, Role.class);
        try {
            updateById(role);
        } catch (Exception e) {
            throw new ServiceException("更新失败");
        }
    }

    @Override
    public void destroy(Long id) {
        try {
            // 删除角色时需要先删除用户与当前角色关联的数据和角色与权限关联的数据
            userRoleService.destroyByRoleId(id);
            rolePermissionService.destroyByRoleId(id);
            removeById(id);
        } catch (Exception e) {
            throw new ServiceException("删除失败");
        }
    }

    @Override
    public void assignPermission(Long id, List<Long> permissionIds) {

        // 检查 roleIds 是否均存在
        if (permissionService.countByIds(permissionIds) != permissionIds.size()){
            throw new ServiceException("分配中有不存在的权限，请检查");
        }

        List<String> permissionIdentities = permissionService.getIdentityByIds(permissionIds);
        rolePermissionService.assignPermissions(id, permissionIds, permissionIdentities);
    }
}
